package com.cysyz.mylib.io.filesavetool.impl;

import com.cysyz.mylib.io.dirgenerator.IDirGenerator;
import com.cysyz.mylib.io.filenamegenerator.IFileNameGenerator;
import com.cysyz.mylib.io.filesavetool.IFileSaveTool;
import com.cysyz.mylib.io.filesavetool.ISaveFileToRemoteTool;
import com.cysyz.mylib.io.realpathgenerator.IRealPathGenerator;
import org.springframework.util.FileCopyUtils;

import java.io.File;
import java.io.IOException;

/**
 * @ClassName: FileSaveTool
 * @Description: 上传文件到本地或远程服务器时，被保存的文件的一般结构为【本地或远程服务器的地址+某个目录+中间目录+文件名称】。
 * 				例如：
 * 				本地或远程服务器的地址  c:\
 * 				某个目录  pic
 * 				中间目录  今天的日期格式的目录结构：如2014\2\17
 * 				文件名称 uuid格式的文件名
 * 				IMiddlePathGenerator接口用于创建中间目录
 * 				IFileNameGenerator接口用于创建文件名
 * @author 崔勇	cysyz1229@gmail.com
 * @date 2014-2-17 上午11:02:35
 */
public class FileSaveTool implements IFileSaveTool {
	private IDirGenerator dirGenerator;
	private IFileNameGenerator fileNameGenerator;
    IRealPathGenerator realPathGenerator;

	/**
	 * <p>Title: </p>
	 * <p>Description: </p>
	 * @param middlePathGenerator 
	 * @param fileNameGenerator
	 */
	public FileSaveTool(IDirGenerator middlePathGenerator,
			IFileNameGenerator fileNameGenerator) {
		super();
		this.dirGenerator = middlePathGenerator;
		this.fileNameGenerator = fileNameGenerator;
	}

	/**
	 * <p>Title: </p>
	 * <p>Description: </p>
	 * @param fileNameGenerator
	 */
	public FileSaveTool(IFileNameGenerator fileNameGenerator) {
		super();
		this.dirGenerator = new IDirGenerator() {

			public String generate(String prefixDir,
                                   String postfixDir) {
				return "";
			}
		};
		this.fileNameGenerator = fileNameGenerator;
	}

    public FileSaveTool(IDirGenerator dirGenerator, IFileNameGenerator fileNameGenerator, IRealPathGenerator realPathGenerator) {
        this.dirGenerator = dirGenerator;
        this.fileNameGenerator = fileNameGenerator;
        this.realPathGenerator = realPathGenerator;
    }

    public FileSaveTool() {

    }


    /** @Title: saveFile
	 * @Description: TODO
	 * @Author: 崔勇	cysyz1229@gmail.com
	 * @Version: V1.00
	 * @Date 2014-2-17 上午11:28:00
	 * @param srcFile 要保存的文件
	 * @param srcFileName   要保存的文件名称，像web中文件上传时，srcFile只是一个服务端接受来自客户端的文件后生成的临时文件，并不是客户端上传时的那个文件。因此客户端的文件名称需要另外提供
	 * @param saveDir 文件的保存目录
	 * @return 文件保存的逻辑路径
	 */
	public String saveFile(File srcFile, String srcFileName, String saveDir) throws IOException {

		String afterPopulateSaveDir = dirGenerator.generate(saveDir, null);
		// 不包含物理根目录的路径名称
		//String fullLogicSavePath = saveDir == null ? "" : saveDir + "/"
		//		+ saveDir;
		//File destDir = new File(savePhysicalBasePath, fullLogicSavePath);
        String realSaveDir = realPathGenerator.getRealPath(afterPopulateSaveDir);
        //目标目录
        File destDir = new File(realSaveDir);
		if (!destDir.exists()) {
			destDir.mkdirs();
		}

		String saveFileName = fileNameGenerator.generate(srcFileName);
		File destFile = new File(destDir, saveFileName);
        FileCopyUtils.copy(srcFile, destFile);
		//srcFile.renameTo(destFile);

        String fullLogicdestPath = afterPopulateSaveDir + "/" + destFile.getName();
		return fullLogicdestPath;
	}

	/** @Title: saveFile
	 * @Description: TODO
	 * @Author: 崔勇	cysyz1229@gmail.com
	 * @Version: V1.00
	 * @Date 2014-2-17 上午11:28:00
	 * @param srcFileBytes
	 * @param srcFileName
	 * @param saveBaseURL
	 * @param saveDir
	 * @param saveFileToRemoteTool
	 * @return
	 */
	public String saveFile(byte[] srcFileBytes, String srcFileName,
			String saveBaseURL, String saveDir,
			ISaveFileToRemoteTool saveFileToRemoteTool) {

		return saveFile0(srcFileBytes, srcFileName, saveBaseURL, saveDir, null,
				saveFileToRemoteTool);
	}

	/**
	 * @Title: saveFile0
	 * @Description: TODO
	 * @Author: 崔勇	cysyz1229@gmail.com
	 * @Version: V1.00
	 * @Date 2014-2-17 上午11:03:52
	 * @param srcFileBytes 文件字节
	 * @param srcFileName  要保存的文件的名字
	 * @param saveBaseURL 要保存到的目的地的URL地址
	 * @param saveDir 要把文件保存到的目标URL地址的某个目录
	 * @param suffix 文件的后缀
	 * @param saveFileToRemoteTool 
	 * @return
	 */
	private String saveFile0(byte[] srcFileBytes, String srcFileName,
			String saveBaseURL, String saveDir,
			String suffix,
			ISaveFileToRemoteTool saveFileToRemoteTool) {
		String middlePath = dirGenerator.generate(srcFileName,
                saveBaseURL);
		String saveFileName = fileNameGenerator.generate(srcFileName);

		StringBuilder logicTargetPath = new StringBuilder(saveDir == null ? ""
				: saveDir);
		logicTargetPath.append("/");
		logicTargetPath.append(middlePath);
		logicTargetPath.append("/");
		logicTargetPath.append(saveFileName);
		
		if (suffix != null) {
			logicTargetPath.append(suffix);
		}
		
		String logicTargetStr = logicTargetPath.toString().replaceAll("[/]+", "/");
		String fullTargetPath = saveBaseURL + "/" + logicTargetStr;
		fullTargetPath = fullTargetPath.replaceAll("[/]+", "/");
		fullTargetPath = fullTargetPath.replaceAll("http:/", "http://");
		saveFileToRemoteTool.save(srcFileBytes, fullTargetPath.toString());
		return logicTargetStr;
	}

	/** @Title: saveFile
	 * @Description: TODO
	 * @Author: 崔勇	cysyz1229@gmail.com
	 * @Version: V1.00
	 * @Date 2014-2-17 上午11:28:00
	 * @param srcFileBytes
	 * @param srcFileName
	 * @param saveBaseURL
	 * @param saveDir
	 * @param suffix
	 * @param saveFileToRemoteTool
	 * @return
	 */
	public String saveFile(byte[] srcFileBytes, String srcFileName,
			String saveBaseURL, String saveDir, String suffix,
			ISaveFileToRemoteTool saveFileToRemoteTool) {
		return this.saveFile0(srcFileBytes, srcFileName, saveBaseURL, saveDir, suffix, saveFileToRemoteTool);
	}
}
